/*
Copyright (c) 2023 China Mobile Information Technology Co., Ltd
OpenGauss Operator is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/

package v1

import (
	v1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.

// OpenGaussClusterSpec defines the desired state of OpenGaussCluster
type OpenGaussClusterSpec struct {
	// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
	// Important: Run "make" to regenerate code after modifying this file

	// 部署架构: split/merge
	Architecture string `json:"architecture,omitempty"`
	// 网络类型: overlay/underlay
	NetworkType string `json:"networkType,omitempty"`
	// 数据节点数量
	DataNodeNum *int32 `json:"dataNodeNum,omitempty"`
	// true：人工维护，false：operator维护
	Maintenance bool `json:"maintenance,omitempty"`
	// 镜像
	Images ContainerImage `json:"images,omitempty"`
	// gaussDB 资源规格
	DBResources ResourceList `json:"dbResources,omitempty"`
	// gaussDB 存储模板
	DBStorage DBStorageTemplate `json:"dbStorage,omitempty"`
	// 对外服务端口,overlay模式下指的是起始端口
	Ports *int32 `json:"ports,omitempty"`
	// 备份恢复
	BackRecovery BackRecoverySpec `json:"backRecovery,omitempty"`
	// switchover message
	Switchover SwitchoverMessage `json:"switchover,omitempty"`
	// 备机重建
	StandbyReconstruct StandbyReconstructSpec `json:"standbyReconstruct,omitempty"`
	// 初始化(gauss账号密码、权限设置)
	IsInit bool `json:"isInit,omitempty"`
	// 节点驱逐
	InstanceMigration InstanceMigrationSpec `json:"instanceMigration,omitempty"`
}

type InstanceMigrationSpec struct {
	Instance string `json:"instance,omitempty"`
	Status   string `json:"status,omitempty"`
	Message  string `json:"message,omitempty"`
}

type StandbyReconstructSpec struct {
	ExecuteInstance string `json:"executeInstance,omitempty"`
	ProblemInstance string `json:"problemInstance,omitempty"`
	Status          string `json:"status,omitempty"`
	Message         string `json:"message,omitempty"`
}

type DBStorageTemplate struct {
	// storageType: localstorage/sharestorage/mix
	StorageType      string            `json:"storageType,omitempty"`
	StorageClassName string            `json:"storageClassName,omitempty"`
	DiskCapacity     resource.Quantity `json:"diskCapacity,omitempty"`
}

type SwitchoverMessage struct {
	TargetMasterPod string `json:"targetMasterPod,omitempty"`
	Status          string `json:"status,omitempty"`
}

type BackRecoverySpec struct {
	Transfer       Transfer       `json:"transfer,omitempty"`
	CronBackupTime string         `json:"cronBackupTime,omitempty"`
	Backups        []BackupSpec   `json:"backups,omitempty"`
	Recoveries     []RecoverySpec `json:"recoveries,omitempty"`
}

type BackupSpec struct {
	PodName string `json:"podName,omitempty"`
	Status  string `json:"status,omitempty"`
}

type RecoverySpec struct {
	PodName      string `json:"podName,omitempty"`
	BackFileName string `json:"backFileName,omitempty"`
	Status       string `json:"status,omitempty"`
}

type Transfer struct {
	// 备份文件远端地址
	Address string `json:"address,omitempty"`
	// 备份文件传输方式，目前只支持scp/s3
	Mode string `json:"mode,omitempty"`
}

type ResourceList struct {
	Limits   map[string]resource.Quantity `json:"limits,omitempty"`
	Requests map[string]resource.Quantity `json:"requests,omitempty"`
}

type ContainerImage struct {
	GaussDB             string `json:"gaussDB,omitempty"`
	GaussExporter       string `json:"gaussExporter,omitempty"`
	GaussBackupRecovery string `json:"gaussBackupRecovery,omitempty"`
}

// OpenGaussClusterStatus defines the observed state of OpenGaussCluster
type OpenGaussClusterStatus struct {
	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
	// Important: Run "make" to regenerate code after modifying this file
	State              OpenGaussClusterState   `json:"state,omitempty"`
	Conditions         []OpenGaussPodCondition `json:"conditions,omitempty"`
	CmsConditions      []OpenGaussPodCondition `json:"cmsConditions,omitempty"`
	Replicas           *int32                  `json:"replicas,omitempty"`
	CurrentReplicas    int32                   `json:"currentReplicas,omitempty"`
	CurrentCmsReplicas int32                   `json:"currentCmsReplicas,omitempty"`
	Message            string                  `json:"message,omitempty"`
}

type OpenGaussPodCondition struct {
	Name     string      `json:"name,omitempty"`
	Ips      []string    `json:"ips,omitempty"`
	NodeName string      `json:"nodeName,omitempty"`
	NodeIp   string      `json:"nodeIp,omitempty"`
	Phase    v1.PodPhase `json:"phase,omitempty"`
	State    string      `json:"state,omitempty"`
	Message  string      `json:"message,omitempty"`
}

type OpenGaussClusterState string

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status

// OpenGaussCluster is the Schema for the opengaussclusters API
type OpenGaussCluster struct {
	metaV1.TypeMeta   `json:",inline"`
	metaV1.ObjectMeta `json:"metadata,omitempty"`

	Spec   OpenGaussClusterSpec   `json:"spec,omitempty"`
	Status OpenGaussClusterStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// OpenGaussClusterList contains a list of OpenGaussCluster
type OpenGaussClusterList struct {
	metaV1.TypeMeta `json:",inline"`
	metaV1.ListMeta `json:"metadata,omitempty"`
	Items           []OpenGaussCluster `json:"items"`
}

func init() {
	SchemeBuilder.Register(&OpenGaussCluster{}, &OpenGaussClusterList{})
}
